﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Pavilion
{
    public class PolygonCollisionData
    {
        internal event Action Disposed;

        private bool hasChanged;
        private List<Action<PolygonCollisionData>> collisionChangedActionList;

        internal PhysicalData PhysicalData { get; private set; }
        public List<PolygonPhysicalData> IntersectedPolygons { get; private set; }
        public List<PolygonPhysicalData> NewIntersectedPolygons { get; private set; }
        public List<PolygonPhysicalData> RemovedIntersectedPolygons { get; private set;  }

        public PolygonCollisionData(PhysicalData physicalData)
        {
            this.PhysicalData = physicalData;
            this.collisionChangedActionList = new List<Action<PolygonCollisionData>>();

            IntersectedPolygons = new List<PolygonPhysicalData>();
            NewIntersectedPolygons = new List<PolygonPhysicalData>();
            RemovedIntersectedPolygons = new List<PolygonPhysicalData>();
        }

        internal void Dispose()
        {
            OnDisposed();

            IntersectedPolygons = null;
            NewIntersectedPolygons = null;
            RemovedIntersectedPolygons = null;
            PhysicalData = null;
            collisionChangedActionList = null;
            Disposed = null;
        }

        internal void RegisterToCollisionChanged(Action<PolygonCollisionData> collisionChangedAction)
        {
            collisionChangedActionList.Add(collisionChangedAction);
        }

        internal void NotifyIntersectionChanged()
        {
            if (hasChanged)
            {
                hasChanged = false;

                foreach (Action<PolygonCollisionData> collisionChangedAction in collisionChangedActionList)
                    collisionChangedAction.Invoke(this);
            }
        }

        internal void AddPolygon(PolygonPhysicalData polygonData)
        {
            if (!IntersectedPolygons.Contains(polygonData))
            {
                if (!hasChanged)
                {
                    RemovedIntersectedPolygons.Clear();
                    NewIntersectedPolygons.Clear();
                }

                IntersectedPolygons.Add(polygonData);
                NewIntersectedPolygons.Add(polygonData);
                hasChanged = true;
            }
        }

        internal void RemovePolygon(PolygonPhysicalData polygonData)
        {
            if (IntersectedPolygons.Remove(polygonData))
            {
                if (!hasChanged)
                {
                    RemovedIntersectedPolygons.Clear();
                    NewIntersectedPolygons.Clear();
                }

                RemovedIntersectedPolygons.Add(polygonData);
                hasChanged = true;
            }
        }

        private void OnDisposed()
        {
            if (Disposed != null)
                Disposed();
        }
    }
}
